package concurrent.c_005_AtomicXXX_CAS;

/**
 * https://www.cnblogs.com/jhxxb/p/11533938.html
 * CAS（Compare and Swap），即比较并替换，实现并发算法时常用到的一种技术。
 * CAS 的思想很简单：三个参数，一个当前内存值 V、旧的预期值 A、即将更新的值 B，当且仅当预期值 A 和内存值 V 相同时，
 * 将内存值修改为 B 并返回 true，否则什么都不做，并返回 false。
 * 和 CAS 相关的一个概念是原子操作。原子操作是不可被中断的一个或一系列操作。而 CAS 则是 Java 中保证原子操作的一种方式。
 * 从 Java1.5 开始，JDK 的并发包里就提供了一些类来支持原子操作，都是以 Atomic 开头。
 * volatile 不能保证类似 i++ 这样操作的原子性，CAS 能够保证。
 */
public class T03_HelloCAS {
    static class M {
        public static int i = 0;
    }

    public final int getIntVolatile(long offset) {
        return M.i;
    }

    /**
     * i++ 实现，依赖 CAS
     */
    public final int getAndAddInt(M o, long offset, int delta) {
        int v;
        do {
            v = getIntVolatile(offset);
        } while (!compareAndSetInt(o, offset, v, v + delta)); // 自旋 CAS 如果长时间不成功，会给 CPU 带来非常大的执行开销
        return v;
    }

    /**
     * CAS
     *
     * @param o        被替换的对象
     * @param offset   当前内存值的偏移量
     * @param expected 旧的预期值
     * @param x        即将更新的值
     * @return 是否替换成功
     */
    public final synchronized boolean compareAndSetInt(M o, long offset, int expected, int x) {
        if (getIntVolatile(offset) == expected) {
            o.i = x;
            return true;
        }
        return false;
    }
}
